package com.aotain.oframework.util.bean;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;

import org.apache.commons.lang.StringUtils;

/**
 * @author Jacob.cw.Zhang@gmail.com
 */
public class MapFactoryBean implements FactoryBean<Map<String, String>>{
	
	private static final Logger logger = LoggerFactory.getLogger(MapFactoryBean.class);
	private String mapPropertyName;
	private Properties properties;
	
	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	public Map<String, String> getObject() throws IOException {
		Properties props = properties;
		Map<String, String> map = new HashMap<String, String>();
		boolean valid = true;
		String keyList = props.getProperty(mapPropertyName + ".list");
		if (StringUtils.isEmpty(keyList)) {
			logger.error("Failed to read map '{}', missing list property.", mapPropertyName);
			valid = false;
		} else {
			valid = createMap(props, map, keyList);
		}
		if (valid) {
			return map;
		} else {
			throw new IllegalStateException("Failed to read map '" + mapPropertyName + "'.");
		}
	}
	
	private boolean createMap(final Properties props, final Map<String, String> map, final String keyList) {
		boolean valid = true;
		String[] keys = StringUtils.split(keyList, ",");
		for (String key : keys) {
			String value = props.getProperty(mapPropertyName + "." + key);
			if (value == null) {
				logger.error("Failed to read map '{}': Missing value for key '{}'", mapPropertyName, key);
				valid = false;
			} else {
				map.put(key, value);
			}
		}
		return valid;
	}

	public Class<?> getObjectType() {
		return Map.class;
	}

	public boolean isSingleton() {
		return true;
	}

	/**
	 * @param mapPropertyName the mapPropertyName to set
	 */
	public void setMapPropertyName(final String mapPropertyName) {
		this.mapPropertyName = mapPropertyName;
	}
	
}
